package com.song.tools.core.util;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * Aop工具
 *
 * @author song tools
 * @since 2024-07-24
 */
@Slf4j
public abstract class AopUtils {

    /**
     * 获取目标方法上的注解。
     * <p>
     * 该方法旨在从给定的JoinPoint中提取目标方法，并检查该方法上是否声明了指定的注解类型。
     * 如果目标方法存在且声明了指定的注解，则返回该注解实例；否则，返回null。
     *
     * @param point           切点对象，代表正在执行的切面逻辑所处的位置。
     * @param annotationClass 指定的注解类，用于查找目标方法上是否声明了该类型的注解。
     * @param <T>             泛型参数，表示注解的类型，必须是Annotation的子类型。
     * @return 如果目标方法上声明了指定的注解，则返回该注解的实例；否则，返回null。
     */
    public static <T extends Annotation> T getTargetAnnotation(JoinPoint point, Class<T> annotationClass) {
        try {
            T annotation = null;
            if (point.getSignature() instanceof MethodSignature) {
                Method method = ((MethodSignature) point.getSignature()).getMethod();
                if (method != null) {
                    annotation = method.getAnnotation(annotationClass);
                }
            }
            return annotation;
        } catch (Exception e) {
            log.warn("获取 {}.{} 的 @{} 注解失败", point.getSignature().getDeclaringTypeName(), point.getSignature().getName(), annotationClass.getName(), e);
            return null;
        }
    }
}
